
package com.qf.controller;


import com.qf.service.GoodsProductgService;
import com.qf.service.GoodsService;
import com.qf.service.OrderService;
import com.qf.service.UserService;
import com.qf.util.ResponseUtil;
import com.qf.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.sql.Connection;
import java.util.*;


/**
 * @author Wy
 * @version V1.0
 * @Project MavenDemo
 * @Package com.qf.controller
 * @Description:
 * @Date 2022/6/18 17:36
 */

@RestController
@CrossOrigin("*")
@RequestMapping("/dashboard")
public class IndexController {
    @Autowired
    private UserService userService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private GoodsProductgService goodsProductgService;

    @GetMapping("")
    public  Object dashboard(){
        //统计用户数量
        int countUser = userService.countUser();
        //统计商品数量
        int countGoods = goodsService.countGoods();
        //统计订单数量
        int countOrder = orderService.countOrder();
        //统计货品数量
        int countGoodsProduct = goodsProductgService.countGoodsProduct();
        //5. 将统计的数据封装到map中, 返回
        HashMap<String,Object> data = new HashMap<>();
        data.put("userTotal", countUser);
        data.put("goodsTotal", countGoods);
        data.put("productTotal",countGoodsProduct);
        data.put("orderTotal",countOrder);

        return ResponseUtil.ok(data);
    }

    /**
     *
     * @return
     */
    @RequestMapping("/chart")
     public Object chart(){
         //1.统计多少天内的用户增长量
         List<DayStatis> userCount = userService.incrCount();
         //2.统计多少天内商品的销售额和销售数量
         List<DayStatis> goodsCount = orderService.incrCount();
         //3. 根据分类统计每个分类的商品销售额
         List<CategorySellAmts> categoryCount = orderService.categoryCount();

        CategorySellVo categorySellVo=fetchCategorySell(categoryCount);
        //4.合并两个结果的日期数据
        String[] dayData = dayData(goodsCount, userCount);
        //转换并合并统计数据, 需要合并日期, 用户数据, 订单数据
        UserOrderCntVo userOrderCntVo = new UserOrderCntVo();
        //用户数据, 合并日期和用户数据统计结果
        userOrderCntVo.setUserCnt(fetchArrayCnt(dayData,userCount));
        //订单数据, 合并日期和订单数据统计结果
        userOrderCntVo.setOrderCnt(fetchArrayCnt(dayData, goodsCount));
        //日期数据
        userOrderCntVo.setDayData(dayData);
        //转换统计结果为前端需要的, 日期, 订单数量, 订单金额数据
        OrderAmtsVo vo = fetchOrderAmtVo(goodsCount);

        //4.把数据封装到MAP中
        HashMap<String,Object> data = new HashMap<>();
         data.put("categorySell",categorySellVo);
        data.put("orderAmts",vo);
        data.put("userOrderCnt",userOrderCntVo);

        return  ResponseUtil.ok(data);
    }

    /**
     * 补全日期数据
     * @param goodsCount
     * @param userCount
     * @return
     */
    private String[] dayData(List<DayStatis> goodsCount, List<DayStatis> userCount){
        HashSet<String> days = new HashSet<>();
        //将对象的日期数据放入集合当中，set几个有单一数据功能
        for (DayStatis dayStatis : goodsCount) {
            days.add(dayStatis.getDayStr());
        }
        for (DayStatis dayStatis : userCount) {
            days.add(dayStatis.getDayStr());
        }
        //然后放入LIst集合当中
        ArrayList<String> arrayList = new ArrayList<>(days);
          //将日期进行排序
        Collections.sort(arrayList);
        //把list集合转化为数组
        String[] strings = arrayList.toArray(new String[0]);
        return strings;
    }

    /**
     * 统计集合中获取的订单数量, 用户数量, 如果对应日期没有统计的数据, 则设置为0
     * @param dayData
     * @param dayStatisCnts
     * @return
     */
    private int[] fetchArrayCnt(String[] dayData, List<DayStatis> dayStatisCnts){
        //设置存放统计订单数量的数字, 和日期数组同样长度
           int[] arrCnts =new int[dayData.length];

           //遍历日期数组
        for (int i = 0; i < dayData.length; i++) {
            //订单量默认为0
             int datcnt=0;
            //当前循环出的日期字符串
           String DayStr=dayData[i];
            //遍历日期和订单统计的集合数据
            for (DayStatis dayStatisCnt : dayStatisCnts) {
                if(DayStr.equals(dayStatisCnt.getDayStr())){
                    //如果数组中的日期和集合中的日期对应, 那么拿出对应的统计的订单量数据,
                    //赋值给上面声明的全局数组
                    datcnt = dayStatisCnt.getCnts();
                    //跳出循坏
                    break;
                }
            }
            arrCnts[i]=datcnt;
        }
        return arrCnts;

    }

    /**
     * 统计封装订单的销售额和订单数量数据
     * @param orderCnts
     * @return
     */
    private OrderAmtsVo fetchOrderAmtVo(List<DayStatis> orderCnts){
        OrderAmtsVo vo = new OrderAmtsVo();
        //传入统计数据集合大小
        int size=0;
        if(orderCnts!=null && orderCnts.size()>0){
            size=orderCnts.size();
        }
        //用来存日期数据
         String[] dayData=new String[size];
        //用来存订单数量
          int[] orderData=new int[size];
        //用来存订单每天总金额
          BigDecimal[] moneyDate=new BigDecimal[size];
        //遍历统计的集合数据, 获取日期, 订单数量, 订单金额
        for (int i = 0; i < size; i++) {
           dayData[i]=orderCnts.get(i).getDayStr();
            orderData[i] = orderCnts.get(i).getCnts();
            moneyDate[i]=orderCnts.get(i).getAmts();
        }
        vo.setDayData(dayData);
        vo.setOrderCntData(orderData);
        vo.setOrderAmtData(moneyDate);


        return vo;
    }



    /**
     * 封装前端需要的根据分类统计销售额实体数据
     * @param list
     * @return
     */
    private CategorySellVo fetchCategorySell(List<CategorySellAmts> list){
        CategorySellVo vo = new CategorySellVo();

        if(list==null||list.size()==0){
            return vo;
        }
        //new一个新数组把遍历的分类名字放里面
         String[] categoryNameArray=new String[list.size()];
        if(list!=null){
            for (int i = 0; i < list.size(); i++) {
                //获取分类名字给数组
                categoryNameArray[i]=list.get(i).getName();
            }
        }

        //分类名字数组，封装分类名字数组
        vo.setCategoryNames(categoryNameArray);
        //分类名字和统计的金额数据
        vo.setCategorySellData(list);

        return vo;
    }





}

